import Icon from '@/components/Icon'
import styles from './index.module.scss'
import { useDispatch, useSelector } from 'react-redux'
import { useEffect, useState } from 'react'
import {
  addChannelAsync,
  delChannelAsync,
  getAllChannelAsync,
} from '@/store/actions/home'
// 按需导入
import differenceBy from 'lodash/differenceBy'
import classNames from 'classnames'
import { error } from '@/utils/tools'

/**
 * 频道管理组件
 * @param {Number} props.tabActiveIndex 用户选中的频道的索引
 * @param {Function} props.onClose 关闭频道管理抽屉时的回调函数
 * @param {Function} props.onChannelClick 当点击频道列表中的某个频道时的回调函数
 */
const Channels = ({ tabActiveIndex, onClose, onChannelClick }) => {
  // 推荐频道数据不能直接获取：需要用户频道数据和所有频道数据做差集
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(getAllChannelAsync())
  }, [dispatch])
  // 用户的频道数据
  const userChannels = useSelector((state) => state.home.userChannels)
  // 所有的频道数据
  const allChannels = useSelector((state) => state.home.allChannels)
  // 推荐的频道数据:所有频道 - 我的频道
  // 从以上2个数组中获取交集
  // 方式一：数组函数
  /* const optionChannels = allChannels.filter((item) => {
    // index为-1代表找不到
    return userChannels.findIndex((v) => v.id === item.id) === -1
  }) */
  // 方式二：loadash
  const optionChannels = differenceBy(allChannels, userChannels, 'id')

  // 我的频道的编辑和保存状态
  const [editable, setEditable] = useState(false)

  // 点击推荐频道中的频道进行添加当前点击的频道到我的频道中
  const onAddChannel = (channel) => {
    dispatch(addChannelAsync(channel))
  }

  // 点击我的频道进行跳转
  const onChannelClickHandle = (channel, index) => {
    if (editable) {
      // 删除
      delChannel(channel, index)
    } else {
      // 跳转
      onChannelClick(index)
    }
  }

  // 删除我的频道
  const delChannel = async (channel, index) => {
    // 1.推荐频道不能删除
    if (channel.id === 0) return error('推荐频道不能删除')
    // 2.至少保留4个频道
    if (userChannels.length <= 4) return error('请至少保留4个频道')
    await dispatch(delChannelAsync(channel))
    // 3.处理高亮
    if (index === tabActiveIndex) {
      // 该频道已经被删除，tabs上面就没有该频道了，回到推荐
      onChannelClick(0)
    }
    if (tabActiveIndex > index) {
      // 索引-1
      onChannelClick(index - 1)
    }
  }

  return (
    <div className={styles.root}>
      {/* 顶部栏：带关闭按钮 */}
      <div className="channel-header">
        <Icon type="iconbtn_channel_close" onClick={onClose} />
      </div>

      {/* 频道列表 */}
      <div className="channel-content">
        {/* 当前已选择的频道列表 */}
        <div className={classNames('channel-item', { edit: editable })}>
          <div className="channel-item-header">
            <span className="channel-item-title">我的频道</span>
            <span className="channel-item-title-extra">
              {editable ? '点击删除频道' : '点击进入频道'}
            </span>
            <span
              className="channel-item-edit"
              onClick={() => setEditable(!editable)}
            >
              {editable ? '完成' : '编辑'}
            </span>
          </div>
          {userChannels?.length > 0 && (
            <div className="channel-list">
              {userChannels.map((item, index) => (
                <span
                  key={item.id}
                  className={classNames('channel-list-item', {
                    selected: index === +tabActiveIndex,
                  })}
                  onClick={() => onChannelClickHandle(item, index)}
                >
                  {item.name}
                  <Icon
                    type="iconbtn_tag_close"
                    onClick={() => delChannel(item, index)}
                  />
                </span>
              ))}
            </div>
          )}
        </div>

        {/* 推荐的频道列表 */}
        <div className="channel-item">
          <div className="channel-item-header">
            <span className="channel-item-title">频道推荐</span>
            <span className="channel-item-title-extra">点击添加频道</span>
          </div>
          {optionChannels?.length > 0 && (
            <div className="channel-list">
              {optionChannels.map((item) => (
                <span
                  key={item.id}
                  className="channel-list-item"
                  onClick={() => onAddChannel(item)}
                >
                  + {item.name}
                </span>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  )
}

export default Channels
